package xcmg.device.service.agentReturn;


import com.github.pagehelper.PageInfo;
import yb.ecp.fast.infra.util.PageHelperPlus;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.account.ArapDetailDO;
import xcmg.device.dao.entity.agentReturn.AgentReturnDO;
import xcmg.device.dao.entity.agentReturn.AgentReturnDetailDO;
import xcmg.device.dao.entity.sale.SalesOutBillDO;
import xcmg.device.dao.entity.sale.SalesOutBillDetailDO;
import xcmg.device.dao.mapper.account.ArapDetailMapper;
import xcmg.device.dao.mapper.agentReturn.AgentReturnDOMapper;
import xcmg.device.dao.mapper.agentReturn.AgentReturnDetailDOMapper;
import xcmg.device.dao.mapper.sale.SalesOutBillDetailMapper;
import xcmg.device.dao.mapper.sale.SalesOutBillMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseInboundDetailMapper;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.ExportUtil;
import xcmg.device.infra.enums.AgentReturnEnum;
import xcmg.device.infra.enums.AgentReturnInboundStatusEnum;
import xcmg.device.infra.enums.AgentReturnStatusEnum;
import xcmg.device.infra.enums.BillDesc;
import xcmg.device.infra.enums.WhetherTypeEnum;
import xcmg.device.service.GenDocumentService;
import xcmg.device.service.vo.agentReturn.AgentReturnAddVO;
import xcmg.device.service.vo.agentReturn.AgentReturnAuditVO;
import xcmg.device.service.vo.agentReturn.AgentReturnDetailAddVO;
import xcmg.device.service.vo.agentReturn.AgentReturnModifyVO;
import xcmg.device.service.vo.agentReturn.AgentReturnQueryVO;
import xcmg.device.service.vo.agentReturn.AgentReturnShowVO;
import xcmg.device.service.warehouse.WarehouseInboundService;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.infra.log.LogHelper;
import yb.ecp.fast.infra.util.ListUtil;
import yb.ecp.fast.infra.util.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;


/**
 * @author: xiali@bkrwin.com
 * @description: 代理商退货Service
 * @date： 2019/6/18 16:33
 **/
@Service
public class AgentReturnService {
    @Autowired
    FastGenClient fastGenClient;
    @Autowired
    AgentReturnDOMapper agentReturnDOMapper;
    @Autowired
    AgentReturnDetailService agentReturnDetailService;
    @Autowired
    AgentReturnDetailDOMapper agentReturnDetailDOMapper;
    @Autowired
    SalesOutBillMapper salesOutBillMapper;
    @Autowired
    SalesOutBillDetailMapper salesOutBillDetailMapper;
    @Autowired
    GenDocumentService genDocumentService;
    @Autowired
    private WarehouseInboundService warehouseInboundService;
    @Autowired
    private HttpServletResponse response;
    @Autowired
    private WarehouseInboundDetailMapper warehouseInboundDetailMapper;
    @Autowired
    private ArapDetailMapper arapDetailMapper;
    /**
     * 查询代理商退货记录
     *
     * @param
     * @return
     */
    public PageCommonVO list(SearchCommonVO<AgentReturnQueryVO> condition) {
        // TODO: 2019/6/18 查询
        PageCommonVO<AgentReturnShowVO> pageCommonVO = new PageCommonVO();

        PageHelperPlus.orderBy("create_time desc");
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<AgentReturnDO> doList = agentReturnDOMapper.getListByQueryVO(condition.getFilters());
        List<AgentReturnShowVO> voList = new ArrayList<>();
        for (AgentReturnDO entity : doList) {
            AgentReturnShowVO model = new AgentReturnShowVO();
            BeanUtils.copyProperties(entity, model);
            //获取结算金额
            BigDecimal settlementAmount = getSettlementAmount(entity);
            model.setSettlementAmount(settlementAmount);
            voList.add(model);
        }
        pageCommonVO.setPageInfo(new PageInfo(doList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    private BigDecimal getSettlementAmount(AgentReturnDO entity) {
        BigDecimal totalPrice = BigDecimal.ZERO;
        List<AgentReturnDetailDO> returnDetailDOS = agentReturnDetailDOMapper.getListByReturnId(entity.getId());
        if (returnDetailDOS.isEmpty()) {
            return totalPrice;
        }
        for (AgentReturnDetailDO detailDO : returnDetailDOS) {
            if (3 == detailDO.getReturnInboundStatus()) {
                totalPrice = totalPrice.add(detailDO.getReturnInboundQty().multiply(detailDO.getPrice()));
            } else {
                totalPrice = totalPrice.add(detailDO.getReturnQuantity().multiply(detailDO.getPrice()));
            }
        }
        totalPrice = totalPrice.setScale(2, BigDecimal.ROUND_HALF_DOWN);
        return totalPrice.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : totalPrice;
    }

    /**
     * 新增代理商退货记录
     *
     * @param agentReturnAddVO
     * @param userId
     * @param userName
     * @return ErrorCode
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode add(AgentReturnAddVO agentReturnAddVO, String userId, String userName) throws Exception {
        List<AgentReturnDetailAddVO> list = agentReturnAddVO.getList();
        if (list.isEmpty()) {
            return ErrorCode.Failure;
        }

        String id = fastGenClient.textGuid().getValue();
        if (StringUtils.isBlank(id)){
            LogHelper.monitor("主键生成有误");
            return ErrorCode.Failure;
        }

        AgentReturnDO agentReturnDO = getAgentReturnDO(agentReturnAddVO, userId, userName, id);
        BigDecimal totalAmount = BigDecimal.ZERO;
        //插入供应商退货详细数据，新增途径传入的数据id一定为空，只有修改时可以为空或不为空
        for (AgentReturnDetailAddVO detailAddVO : list) {
            AgentReturnDetailAddVO agentReturnDetailAddVO = new AgentReturnDetailAddVO();
            BeanUtils.copyProperties(detailAddVO, agentReturnDetailAddVO);
            agentReturnDetailAddVO.setReturnId(agentReturnDO.getId());
            agentReturnDetailAddVO.setSalesOutBillDetailId(detailAddVO.getSalesOutBillDetailId());
            ErrorCode ret = agentReturnDetailService.addOrModify(agentReturnDetailAddVO);
            if (ErrorCode.Success.getCode() != ret.getCode()) {
                throw new Exception("新增代理商退货详情失败");
            }
            if (agentReturnDO.getStatus().equals(AgentReturnEnum.WAIT_AUDIT.getCode())) {
                updateSalesBillOutDetail(detailAddVO);
            }

            totalAmount = totalAmount.add(agentReturnDetailAddVO.getPrice().multiply(agentReturnDetailAddVO.getReturnQuantity()));
        }

        agentReturnDO.setTotalAmount(totalAmount.setScale(2,BigDecimal.ROUND_HALF_DOWN));
        Boolean success = agentReturnDOMapper.insertSelective(agentReturnDO) > 0;
        if (!success) {
            LogHelper.error("新增代理商退款记录失败", ErrorCode.Failure.getCode());
            return ErrorCode.Failure;

        }
        return ErrorCode.Success;
    }


    private void returnClientAmount(AgentReturnDO agentReturnDO) {

    }

    private AgentReturnDO getAgentReturnDO(AgentReturnAddVO agentReturnAddVO, String userId, String userName, String id) {
        AgentReturnDO agentReturnDO = new AgentReturnDO();
        BeanUtils.copyProperties(agentReturnAddVO, agentReturnDO);
        agentReturnDO.setId(id);
        agentReturnDO.setReturnNo(genDocumentService.getDocumentNo(BillDesc.SalesReturnNo));
        if (agentReturnAddVO.getSubmitFlag() == 0) {
            agentReturnDO.setStatus(AgentReturnEnum.DRAFT.getCode());
        } else {
            agentReturnDO.setStatus(AgentReturnEnum.WAIT_AUDIT.getCode());
        }
        agentReturnDO.setDeleteFlag(0);
        agentReturnDO.setCreatorId(userId);
        if (null == userName) {
            userName = userId;
        }
        agentReturnDO.setInboundStatus(AgentReturnInboundStatusEnum.NO_INBOUND.getCode());
        agentReturnDO.setCreatorName(userName);
        Date currentTime = new Date();
        agentReturnDO.setCreateTime(currentTime);
        agentReturnDO.setModifierId(userId);
        agentReturnDO.setModifierName(userName);
        agentReturnDO.setModifyTime(currentTime);
        return agentReturnDO;
    }


    /**
     * 审核
     *
     * @param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode audit(AgentReturnAuditVO auditVO, String userId, String userName, String orgId) throws Exception {
        AgentReturnDO agentReturnDO = agentReturnDOMapper.selectByPrimaryKey(auditVO.getId());
        if (null == agentReturnDO) {
            return ErrorCode.Failure;
        }

        Integer status = agentReturnDO.getStatus();
        if ( 3 == status){
            return ErrorCode.ReviewRejectionStatusCannotBeReviewed;
        }

        if (auditVO.getAuditFlag() == 1) {
            agentReturnDO.setStatus(AgentReturnEnum.AUDIT_PASSED.getCode());
            // 审核通过做相应的处理  调用事物表新增接口   构建事务表插入VO
            List<AgentReturnDetailDO> detailDOList = agentReturnDetailDOMapper.getListByReturnId(auditVO.getId());
            if (detailDOList.size() <= 0) {
                return ErrorCode.Failure;
            }
            warehouseInboundService.saveByRefundInbound(agentReturnDO, detailDOList, userId, orgId);
        } else {
            agentReturnDO.setStatus(AgentReturnEnum.RETURN_UPDATE.getCode());
            List<AgentReturnDetailDO> detailDOList = agentReturnDetailDOMapper.getListByReturnId(auditVO.getId());
            if (detailDOList.size() <= 0) {
                return ErrorCode.Failure;
            }
            //若退货单审核不通过，需要撤销之前添加的出库详情数据。
            for (AgentReturnDetailDO record : detailDOList) {
                SalesOutBillDetailDO salesOutBillDetailDO = salesOutBillDetailMapper.selectByPrimaryKey(
                        record.getSalesOutBillDetailId());
                salesOutBillDetailDO.setActualReturnQty(
                        salesOutBillDetailDO.getActualReturnQty().subtract(record.getReturnQuantity()));
                boolean updateResult = salesOutBillDetailMapper.updateByPrimaryKeySelective(salesOutBillDetailDO) > 0;
                if (!updateResult) {
                    throw new Exception("修改销售出库单详情失败");
                }
            }
        }
        agentReturnDO.setReturnAdvice(auditVO.getReturnAdvice());
        if (null == userName) {
            userName = userId;
        }
        Date currentTime = new Date();
        agentReturnDO.setModifierId(userId);
        agentReturnDO.setModifierName(userName);
        agentReturnDO.setModifyTime(currentTime);
        agentReturnDO.setAuditId(userId);
        agentReturnDO.setAuditName(userName);
        agentReturnDO.setAuditTime(currentTime);
        Boolean success = agentReturnDOMapper.updateByPrimaryKeySelective(agentReturnDO) > 0;
        if (!success) {
            LogHelper.error("审核代理商退货记录失败", ErrorCode.Failure.getCode());
            throw new Exception("审核代理商退货记录失败");
        }
        return ErrorCode.Success;
    }


    /**
     * 修改代理商退货记录
     *
     * @param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode modify(AgentReturnModifyVO modifyVO, String userId, String userName) throws Exception {
        List<AgentReturnDetailAddVO> list = modifyVO.getList();
        if (list.isEmpty()) {
            return ErrorCode.Failure;
        }

        int statusCode = modifyVO.getStatus();
        if (statusCode == AgentReturnEnum.WAIT_AUDIT.getCode() || statusCode == AgentReturnEnum.AUDIT_PASSED.getCode()) {
            return ErrorCode.Failure;
        }

        AgentReturnDO agentReturnDO = agentReturnDOMapper.selectByPrimaryKey(modifyVO.getId());
        if (null == agentReturnDO) {
            return ErrorCode.Failure;
        }

        BeanUtils.copyProperties(modifyVO, agentReturnDO);
        if (null == userName) {
            userName = userId;
        }

        Date currentTime = new Date();
        if (modifyVO.getSubmitFlag() == 0) {
            agentReturnDO.setStatus(statusCode);
        } else {
            agentReturnDO.setStatus(AgentReturnEnum.WAIT_AUDIT.getCode());
        }
        agentReturnDO.setModifierId(userId);
        agentReturnDO.setModifierName(userName);
        agentReturnDO.setModifyTime(currentTime);
        //修改后的数据可能的情况：可能比原来少，或者和原来一样只是数量减少了
        List<String> idsDifferenceList = judgeNewReturnDetail(modifyVO);
        if (idsDifferenceList.size() != 0) {
            //说明传入的零件种类减少了，剩下的就是需要被删除的
            for (String id : idsDifferenceList) {
                boolean deleteResult = agentReturnDetailDOMapper.deleteByPrimaryKey(id) > 0;
                if (!deleteResult) {
                    throw new Exception("删除历史代理商退货详情失败");
                }
            }
        }

        BigDecimal totalPrice = BigDecimal.ZERO;
        for (AgentReturnDetailAddVO detailAddVO : list) {
            AgentReturnDetailAddVO agentReturnDetailAddVO = new AgentReturnDetailAddVO();
            BeanUtils.copyProperties(detailAddVO, agentReturnDetailAddVO);
            ErrorCode ret = agentReturnDetailService.addOrModify(agentReturnDetailAddVO);
            if (ErrorCode.Success.getCode() != ret.getCode()) {
                throw new Exception("修改代理商退货详情失败");
            }
            totalPrice = totalPrice.add(agentReturnDetailAddVO.getPrice().multiply(agentReturnDetailAddVO.getReturnQuantity()));
            if (agentReturnDO.getStatus().equals(AgentReturnEnum.WAIT_AUDIT.getCode())) {
                updateSalesBillOutDetail(detailAddVO);
            }
        }

        agentReturnDO.setTotalAmount(totalPrice.setScale(2,BigDecimal.ROUND_HALF_DOWN));
        Boolean success = agentReturnDOMapper.updateByPrimaryKeySelective(agentReturnDO) > 0;
        if (!success) {
            LogHelper.error("修改代理商退货记录失败", ErrorCode.Failure.getCode());
            throw new Exception("修改退货单失败");
        }

        if (agentReturnDO.getStatus().equals(AgentReturnEnum.WAIT_AUDIT.getCode())) {
            updateSalesBillOut(agentReturnDO);
        }

        return ErrorCode.Success;
    }

    private List<String> judgeNewReturnDetail(AgentReturnModifyVO modifyVO) {
        // 此处需要判断传入新list与旧list区别  并作相应处理
        List<String> oldDetailIds = agentReturnDetailDOMapper.getIdListByReturnId(modifyVO.getId());
        List<String> newDetailIds = new ArrayList<>();
        for (AgentReturnDetailAddVO detailAddVO : modifyVO.getList()) {
            newDetailIds.add(detailAddVO.getId());
        }

        oldDetailIds.removeAll(newDetailIds);
        return oldDetailIds;
    }

    /**
     * @Author: xiali
     * @Description: 根据主键删除出库记录
     * @Date: 15:40 2018/1/17 0017
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode discardBatch(List<String> ids, String userId, String userName,String orgId) throws Exception {
        if (ids.size() <= 0) {
            return ErrorCode.IllegalArument;
        }
        for (String id : ids) {
            ErrorCode ret = discard(id, userId, userName,orgId);
            //删除入库详情记录
            if (ret.getCode() != 0) {
                throw new Exception(ErrorCode.Failure.getDesc());
            }
        }
        return ErrorCode.Success;
    }

    /**
     * 删除退货单
     *
     * @param
     * @return
     */
    public ErrorCode discard(String id, String userId, String userName,String orgId) throws Exception {
        AgentReturnDO agentReturnDO = agentReturnDOMapper.selectByPrimaryKey(id);
        if (null == agentReturnDO) {
            return ErrorCode.Failure;
        }

        boolean outboundReturns = this.updateSalesOutboundReturns(agentReturnDO.getId(), null,agentReturnDO.getStatus(), true, false);
        if (!outboundReturns){
            throw new Exception("删除退货单时，更新销售出库单建退回单数量失败");
        }

        if (2 == agentReturnDO.getStatus()){
            //删除事物表
            warehouseInboundService.removeByBusinessOrders(Collections.singletonList(agentReturnDO.getReturnNo()), orgId);
        }
        //未入库且未收款 才能删除
        agentReturnDO.setDeleteFlag(WhetherTypeEnum.YesFlag.getCode());
        if (null == userName) {
            userName = userId;
        }
        Date currentTime = new Date();
        agentReturnDO.setModifierId(userId);
        agentReturnDO.setModifierName(userName);
        agentReturnDO.setModifyTime(currentTime);
        agentReturnDO.setDeleteId(userId);
        agentReturnDO.setDeleteName(userName);
        agentReturnDO.setDeleteTime(currentTime);
        Boolean success = agentReturnDOMapper.updateByPrimaryKeySelective(agentReturnDO) > 0;
        if (!success) {
            LogHelper.error("删除代理商退款记录失败", ErrorCode.Failure.getCode());
            throw new Exception("删除供应商退款单记录失败");
        }
        return ErrorCode.Success;
    }

    private void updateSalesBillOutDetail(AgentReturnDetailAddVO detailAddVO) throws Exception {
        SalesOutBillDetailDO detailDO = salesOutBillDetailMapper.selectByPrimaryKey(detailAddVO.getSalesOutBillDetailId());
        if (null == detailDO) {
            throw new Exception("查询销售出库单详情失败");
        }
        //校验退货数量与销售出库单数量
        BigDecimal newRefundQty = detailDO.getActualReturnQty().add(detailAddVO.getReturnQuantity());
        if (newRefundQty.compareTo(detailDO.getOutboundQty()) > 0){
            throw new Exception("零件"+detailDO.getMaterialNo()+"，创建退回单数量大于实际出库数量");
        }

        detailDO.setActualReturnQty(newRefundQty);
        Boolean updateRet = salesOutBillDetailMapper.updateByPrimaryKeySelective(detailDO) > 0;
        if (!updateRet) {
            LogHelper.error("更新销售出库单详情失败", ErrorCode.Failure.getCode());
            throw new Exception("更新销售出库单详情失败");
        }
    }


    private void updateSalesBillOut(AgentReturnDO agentReturnDO) throws Exception {
        int num = 0;
        SalesOutBillDO salesOutBillDO = salesOutBillMapper.selectByPrimaryKey(agentReturnDO.getSaleOutId());
        if (null == salesOutBillDO) {
            throw new Exception("查询销售出库单失败");
        }
        List<SalesOutBillDetailDO> list = salesOutBillDetailMapper.selectBySalesOutBillNo(salesOutBillDO.getSalesOutBillNo());
        if (list.size() <= 0) {
            throw new Exception("查询销售出库单详情失败");
        } else {
            for (SalesOutBillDetailDO detailDO : list) {
                if (detailDO.getOutboundQty().equals(detailDO.getActualReturnQty())) {
                    num += 1;
                }
            }
        }
        if (num == list.size()) {
            salesOutBillDO.setReturnStatus(AgentReturnStatusEnum.HAS_RETURN.getCode());
        } else {
            salesOutBillDO.setReturnStatus(AgentReturnStatusEnum.PART_RETURN.getCode());
        }
        Boolean updateRet = salesOutBillMapper.updateByPrimaryKeySelective(salesOutBillDO) > 0;
        if (!updateRet) {
            LogHelper.error("更新销售出库单详情失败", ErrorCode.Failure.getCode());
            throw new Exception("更新销售出库单详情失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode manualFinish(String refundNo, String materialsNo, String orgId) throws Exception {
        AgentReturnDO agentReturnDO = agentReturnDOMapper.selectByReturnNo(refundNo,orgId);
        if (agentReturnDO == null) {
            return ErrorCode.IllegalArument;
        }
        if (agentReturnDO.getStatus() == 0) {
            return ErrorCode.DraftingStatusDocumentsNotAllowStatements;
        }

        //更新销售单创建退货单数量
        boolean outboundReturns = this.updateSalesOutboundReturns(agentReturnDO.getId(), materialsNo,agentReturnDO.getStatus(), false, true);
        if (!outboundReturns){
            throw new Exception("修改销售出库单退回数量有误");
        }

        if (StringUtil.isNullOrEmpty(materialsNo))//零件编码为空，更新单据状态为“手动完成”
        {
            agentReturnDOMapper.updateStatus(refundNo, 3, orgId);
            warehouseInboundService.updateState(refundNo, 3, orgId);
            agentReturnDetailDOMapper.updateStatus(agentReturnDO.getId(), 3, null);
            warehouseInboundDetailMapper.updateAllStatus(3, refundNo, orgId);
        } else {
            agentReturnDetailDOMapper.updateStatus(agentReturnDO.getId(), 3, materialsNo);
            warehouseInboundService.updateDetailState(refundNo, materialsNo, null, 3, orgId);
            ErrorCode errorCode = checkBillFinished(refundNo, agentReturnDO.getId(), orgId);
            if (ErrorCode.Success != errorCode) {
                return errorCode;
            }
        }

        Integer totalAmount = agentReturnDetailDOMapper.getTotalAmount(agentReturnDO.getId());
        if (totalAmount <= 0){
            AgentReturnDO updateAgentReturnDO = new AgentReturnDO();
            updateAgentReturnDO.setId(agentReturnDO.getId());
            updateAgentReturnDO.setCheckState(2);
            agentReturnDOMapper.updateByPrimaryKeySelective(updateAgentReturnDO);
        }
        return ErrorCode.Success;
    }

    private ErrorCode checkBillFinished(String billNo, String billId, String orgId) throws Exception {
        List<AgentReturnDetailDO> detailDOList = agentReturnDetailDOMapper.getListByReturnId(billId);
        if (ListUtil.isNullOrEmpty(detailDOList)) {
            throw new Exception("未查询到销售出库单详情列表");
        }
        boolean manul = false;
        boolean flag = true;
        int status;
        for (AgentReturnDetailDO temp : detailDOList) {
            if (3 == temp.getReturnInboundStatus()) {
                manul = true;
            }
            if (3 == temp.getReturnInboundStatus() || 2 == temp.getReturnInboundStatus()) {
                //完成状态
                continue;
            }
            flag = false;
        }
        if (flag) {
            if (manul) {
                status = 3;
            } else {
                status = 2;
            }
        } else {
            status = 1;
        }
        agentReturnDOMapper.updateStatus(billNo, status, orgId);
        warehouseInboundService.updateState(billNo, status, orgId);
        return ErrorCode.Success;
    }

    private boolean updateSalesOutboundReturns(String billId, String materialsNo, Integer isState,boolean isDel, boolean check) {
        List<AgentReturnDetailDO> returnDetailDOS = agentReturnDetailDOMapper.selectByBillIdMate(billId, materialsNo);
        for (AgentReturnDetailDO agentReturnDetailDO : returnDetailDOS) {
            Integer inboundStatus = agentReturnDetailDO.getReturnInboundStatus();
            if (3 == inboundStatus) {
                continue;
            }

            String salesOutBillDetailId = agentReturnDetailDO.getSalesOutBillDetailId();
            BigDecimal thisShipQty = agentReturnDetailDO.getReturnQuantity();
            if (check) {
                BigDecimal inboundQty = agentReturnDetailDO.getReturnInboundQty();
                thisShipQty = thisShipQty.subtract(inboundQty == null ? BigDecimal.ZERO : inboundQty);
            }

            if (isDel && (isState == 0 || isState == 3)) {//删除且保存,审核拒绝状态不扣减销售出库单创建退货数量
                thisShipQty = BigDecimal.ZERO;
            }
            boolean updateResult = this.updateReturnQty(salesOutBillDetailId, thisShipQty);
            if (!updateResult) {
                return false;
            }
        }
        if (isDel) {
            AgentReturnDO agentReturnDO = agentReturnDOMapper.selectByPrimaryKey(billId);
            Integer count = salesOutBillDetailMapper.getCrateQtyBigZeroCount(agentReturnDO.getSaleOutNo());
            if (count <= 0) {
                SalesOutBillDO record = new SalesOutBillDO();
                record.setReturnStatus(0);
                record.setId(agentReturnDO.getSaleOutId());
                return salesOutBillMapper.updateByPrimaryKeySelective(record) > 0;
            }
        }
        return true;
    }

    private boolean updateReturnQty(String detailId, BigDecimal createOutQty){
        SalesOutBillDetailDO salesOutBillDetailDO = salesOutBillDetailMapper.selectByPrimaryKey(detailId);
        if (salesOutBillDetailDO == null) {
            return false;
        }
        BigDecimal actualReturnQty = salesOutBillDetailDO.getActualReturnQty();
        SalesOutBillDetailDO record = new SalesOutBillDetailDO();
        record.setActualReturnQty(actualReturnQty.subtract(createOutQty));
        record.setId(salesOutBillDetailDO.getId());
        return salesOutBillDetailMapper.updateByPrimaryKeySelective(record)>0;
    }

    /**
     * 正常入库
     *
     * @param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode inbound(String id) throws Exception {
        AgentReturnDO agentReturnDO = agentReturnDOMapper.selectByPrimaryKey(id);
        if (null == agentReturnDO) {
            return ErrorCode.Failure;
        }
        List<AgentReturnDetailDO> detailDOS = agentReturnDetailDOMapper.getListByReturnId(id);
        if (detailDOS.size() <= 0) {
            return ErrorCode.Failure;
        }
        for (AgentReturnDetailDO agentReturnDetailDO : detailDOS) {
            //无条码入库
            agentReturnDetailDO.setReturnInboundQty(agentReturnDetailDO.getReturnQuantity());
            agentReturnDetailDO.setReturnInboundStatus(AgentReturnInboundStatusEnum.HAS_INBOUND.getCode());
            int num = agentReturnDetailDOMapper.updateByPrimaryKeySelective(agentReturnDetailDO);
            if (num <= 0) {
                throw new Exception("更新退库单零件详情失败");
            }
        }
        agentReturnDO.setInboundStatus(AgentReturnInboundStatusEnum.HAS_INBOUND.getCode());
        int num = agentReturnDOMapper.updateByPrimaryKeySelective(agentReturnDO);
        if (num <= 0) {
            throw new Exception("更新退库单失败");
        }
        return ErrorCode.Success;
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean updateByInbound(String returnNo, String materialNo, BigDecimal realAmount, Integer singleState, Integer totalState, String orgId) throws Exception {
        AgentReturnDO agentReturnDO = agentReturnDOMapper.selectByReturnNo(returnNo,orgId);
        if (null == agentReturnDO) {
            throw new Exception("未找到退货单据记录");
        }
        AgentReturnDO inboundStatusDO = new AgentReturnDO();
        inboundStatusDO.setId(agentReturnDO.getId());
        inboundStatusDO.setInboundStatus(totalState);
        boolean success = agentReturnDOMapper.updateByPrimaryKeySelective(inboundStatusDO) > 0;

        if (success) {
            AgentReturnDetailDO inDetailDO = agentReturnDetailDOMapper.selectByReturnIdAndMaterialsNo(agentReturnDO.getId(), materialNo);
            if (null == inDetailDO) {
                throw new Exception("未找到退货单详情记录");
            }

            if (realAmount.compareTo(inDetailDO.getReturnQuantity()) > 0) {
                throw new Exception("实际入库数量不能大于退回入库数量");
            }

            inDetailDO.setReturnInboundStatus(singleState);
            inDetailDO.setReturnInboundQty(realAmount);
            success = agentReturnDetailDOMapper.updateByPrimaryKeySelective(inDetailDO) > 0;
            if (!success) {
                throw new Exception("更新退货单零件详情失败");
            }
            //更新销售出库单退货状态
//            ErrorCode errorCode = upUseQuota(realAmount, serviceBorrowInDO, inDetailDO);
//            if (ErrorCode.Success != errorCode) {
//                throw new Exception(errorCode.getDesc());
//            }
        }
        return success;
    }


    //获取退货单信息
    public AgentReturnShowVO item(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }
        AgentReturnDO agentReturnDO = agentReturnDOMapper.selectByPrimaryKey(id);
        if (agentReturnDO == null) {
            return null;
        }
        AgentReturnShowVO agentReturnShowVO = new AgentReturnShowVO();
        BeanUtils.copyProperties(agentReturnDO, agentReturnShowVO);
        return agentReturnShowVO;
    }


    public void export(List<String> ids) throws Exception {
        List<AgentReturnDO> voList = new ArrayList<>();
        for (String id : ids) {
            AgentReturnDO agentReturnDO = agentReturnDOMapper.selectByPrimaryKey(id);
            voList.add(agentReturnDO);
        }
        invokeExport(voList);
    }

    public void exportAll(AgentReturnQueryVO condition) throws Exception {
        //PageHelperPlus.startPage(0, 0, "create_time desc");
        List<AgentReturnDO> doList = agentReturnDOMapper.getListByQueryVO(condition);
        invokeExport(doList);
    }

    private void invokeExport(List<AgentReturnDO> voList) throws Exception {
        String title = "退货入库数据导出";
        String[] rowsName = new String[]{"序号", "退货单号", "销售出库单号", "收款单号", "制单人", "制单时间", "总金额", "销售单类型", "入库状态",
                "审核人", "结算状态", "备注", "零件号", "零件名称", "单位", "退货数量"};
        List<Object[]> dataList = new ArrayList<>();
        Object[] objs;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < voList.size(); i++) {
            AgentReturnDO agentReturnDO = voList.get(i);
            List<AgentReturnDetailDO> doList = agentReturnDetailDOMapper.getListByReturnId(agentReturnDO.getId());
            for (AgentReturnDetailDO detailDO : doList) {
                objs = new Object[rowsName.length];
                objs[0] = i + 1;
                objs[1] = agentReturnDO.getReturnNo();
                objs[2] = agentReturnDO.getSaleOutNo();
                objs[3] = agentReturnDO.getReceiptNo();
                objs[4] = agentReturnDO.getCreatorName();
                objs[5] = sdf.format(agentReturnDO.getCreateTime());
                objs[6] = agentReturnDO.getTotalAmount();
                objs[7] = getBillType(agentReturnDO.getSaleType());
                objs[8] = getInboundStatus(agentReturnDO.getInboundStatus());
                objs[9] = agentReturnDO.getAuditName();
                objs[10] = getCheckState(agentReturnDO.getCheckState());
                objs[11] = agentReturnDO.getRemark();
                objs[12] = detailDO.getMaterialNo();
                objs[13] = detailDO.getMaterialDesc();
                objs[14] = detailDO.getUnit();
                objs[15] = detailDO.getReturnQuantity();
                dataList.add(objs);
            }
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private String getInboundStatus(Integer inboundStatus) {
        switch (inboundStatus) {
            case 0:
            default:
                return "未入库";
            case 1:
                return "部分入库";
            case 2:
                return "已入库";
            case 3:
                return "强制结单";
        }
    }

    private String getBillType(Integer billType) {
        switch (billType) {
            case 1:
            default:
                return "普通";
            case 2:
                return "三包";
            case 3:
                return "赠送";
        }
    }

    private String getCheckState(Integer checkState) {
        switch (checkState) {
            case 0:
            default:
                return "未结算";
            case 1:
                return "部分结算";
            case 2:
                return "已结算";
        }
    }

    public BigDecimal getTheAmountOwed(String returnId,String orgId){
        BigDecimal amountOwed = BigDecimal.ZERO;
        AgentReturnDO agentReturnDO = agentReturnDOMapper.selectByPrimaryKey(returnId);
        if (null == agentReturnDO){
            return amountOwed;
        }
        ArapDetailDO arapDetailDO = arapDetailMapper.selectByBillNo(orgId, agentReturnDO.getSaleOutNo());
        if (null == arapDetailDO){
            return amountOwed;
        }
        amountOwed = arapDetailDO.getRemainPrice();
        return amountOwed;
    }
}
